﻿/*
 * User: RSny
 * Date: 5/8/2012
 * Time: 2:44 PM
 */

using System;
using System.Runtime.InteropServices;

namespace Aspects.PInvoke
{
    public partial class Native
    {
        public enum FAMILY : uint
        {
            AF_INET=2,
            AF_INET6=23,
            AF_UNSPEC=0
        }
        public enum FLAGS : uint
        {
            GAA_FLAG_SKIP_UNICAST = 0x0001,
            GAA_FLAG_SKIP_ANYCAST = 0x0002,
            GAA_FLAG_SKIP_MULTICAST = 0x0004,
            GAA_FLAG_SKIP_DNS_SERVER = 0x0008,
            GAA_FLAG_INCLUDE_PREFIX = 0x0010,
            GAA_FLAG_SKIP_FRIENDLY_NAME = 0x0020
        }
        public enum ERROR : uint
        {
            ERROR_SUCCESS = 0,
            ERROR_NO_DATA = 232,
            ERROR_BUFFER_OVERFLOW = 111,
            ERROR_INVALID_PARAMETER = 87
        }
        public enum IF_OPER_STATUS : uint
        {
            IfOperStatusUp = 1,
            IfOperStatusDown,
            IfOperStatusTesting,
            IfOperStatusUnknown,
            IfOperStatusDormant,
            IfOperStatusNotPresent,
            IfOperStatusLowerLayerDown,
        }
        public enum IF_TYPE : uint
        {
            IF_TYPE_OTHER = 1,   // None of the below
            IF_TYPE_REGULAR_1822 = 2,
            IF_TYPE_HDH_1822 = 3,
            IF_TYPE_DDN_X25 = 4,
            IF_TYPE_RFC877_X25 = 5,
            IF_TYPE_ETHERNET_CSMACD = 6,
            IF_TYPE_IS088023_CSMACD = 7,
            IF_TYPE_ISO88024_TOKENBUS = 8,
            IF_TYPE_ISO88025_TOKENRING = 9,
            IF_TYPE_ISO88026_MAN = 10,
            IF_TYPE_STARLAN = 11,
            IF_TYPE_PROTEON_10MBIT = 12,
            IF_TYPE_PROTEON_80MBIT = 13,
            IF_TYPE_HYPERCHANNEL = 14,
            IF_TYPE_FDDI = 15,
            IF_TYPE_LAP_B = 16,
            IF_TYPE_SDLC = 17,
            IF_TYPE_DS1 = 18,  // DS1-MIB
            IF_TYPE_E1 = 19,  // Obsolete; see DS1-MIB
            IF_TYPE_BASIC_ISDN = 20,
            IF_TYPE_PRIMARY_ISDN = 21,
            IF_TYPE_PROP_POINT2POINT_SERIAL = 22,  // proprietary serial
            IF_TYPE_PPP = 23,
            IF_TYPE_SOFTWARE_LOOPBACK = 24,
            IF_TYPE_EON = 25,  // CLNP over IP
            IF_TYPE_ETHERNET_3MBIT = 26,
            IF_TYPE_NSIP = 27,  // XNS over IP
            IF_TYPE_SLIP = 28,  // Generic Slip
            IF_TYPE_ULTRA = 29,  // ULTRA Technologies
            IF_TYPE_DS3 = 30,  // DS3-MIB
            IF_TYPE_SIP = 31,  // SMDS, coffee
            IF_TYPE_FRAMERELAY = 32,  // DTE only
            IF_TYPE_RS232 = 33,
            IF_TYPE_PARA = 34,  // Parallel port
            IF_TYPE_ARCNET = 35,
            IF_TYPE_ARCNET_PLUS = 36,
            IF_TYPE_ATM = 37,  // ATM cells
            IF_TYPE_MIO_X25 = 38,
            IF_TYPE_SONET = 39,  // SONET or SDH
            IF_TYPE_X25_PLE = 40,
            IF_TYPE_ISO88022_LLC = 41,
            IF_TYPE_LOCALTALK = 42,
            IF_TYPE_SMDS_DXI = 43,
            IF_TYPE_FRAMERELAY_SERVICE = 44,  // FRNETSERV-MIB
            IF_TYPE_V35 = 45,
            IF_TYPE_HSSI = 46,
            IF_TYPE_HIPPI = 47,
            IF_TYPE_MODEM = 48,  // Generic Modem
            IF_TYPE_AAL5 = 49,  // AAL5 over ATM
            IF_TYPE_SONET_PATH = 50,
            IF_TYPE_SONET_VT = 51,
            IF_TYPE_SMDS_ICIP = 52,  // SMDS InterCarrier Interface
            IF_TYPE_PROP_VIRTUAL = 53,  // Proprietary virtual/internal
            IF_TYPE_PROP_MULTIPLEXOR = 54,  // Proprietary multiplexing
            IF_TYPE_IEEE80212 = 55,  // 100BaseVG
            IF_TYPE_FIBRECHANNEL = 56,
            IF_TYPE_HIPPIINTERFACE = 57,
            IF_TYPE_FRAMERELAY_INTERCONNECT = 58,  // Obsolete, use 32 or 44
            IF_TYPE_AFLANE_8023 = 59,  // ATM Emulated LAN for 802.3
            IF_TYPE_AFLANE_8025 = 60,  // ATM Emulated LAN for 802.5
            IF_TYPE_CCTEMUL = 61,  // ATM Emulated circuit
            IF_TYPE_FASTETHER = 62,  // Fast Ethernet (100BaseT)
            IF_TYPE_ISDN = 63,  // ISDN and X.25
            IF_TYPE_V11 = 64,  // CCITT V.11/X.21
            IF_TYPE_V36 = 65,  // CCITT V.36
            IF_TYPE_G703_64K = 66,  // CCITT G703 at 64Kbps
            IF_TYPE_G703_2MB = 67,  // Obsolete; see DS1-MIB
            IF_TYPE_QLLC = 68,  // SNA QLLC
            IF_TYPE_FASTETHER_FX = 69,  // Fast Ethernet (100BaseFX)
            IF_TYPE_CHANNEL = 70,
            IF_TYPE_IEEE80211 = 71,  // Radio spread spectrum
            IF_TYPE_IBM370PARCHAN = 72,  // IBM System 360/370 OEMI Channel
            IF_TYPE_ESCON = 73,  // IBM Enterprise Systems Connection
            IF_TYPE_DLSW = 74,  // Data Link Switching
            IF_TYPE_ISDN_S = 75,  // ISDN S/T interface
            IF_TYPE_ISDN_U = 76,  // ISDN U interface
            IF_TYPE_LAP_D = 77,  // Link Access Protocol D
            IF_TYPE_IPSWITCH = 78,  // IP Switching Objects
            IF_TYPE_RSRB = 79,  // Remote Source Route Bridging
            IF_TYPE_ATM_LOGICAL = 80,  // ATM Logical Port
            IF_TYPE_DS0 = 81,  // Digital Signal Level 0
            IF_TYPE_DS0_BUNDLE = 82,  // Group of ds0s on the same ds1
            IF_TYPE_BSC = 83,  // Bisynchronous Protocol
            IF_TYPE_ASYNC = 84,  // Asynchronous Protocol
            IF_TYPE_CNR = 85,  // Combat Net Radio
            IF_TYPE_ISO88025R_DTR = 86,  // ISO 802.5r DTR
            IF_TYPE_EPLRS = 87,  // Ext Pos Loc Report Sys
            IF_TYPE_ARAP = 88,  // Appletalk Remote Access Protocol
            IF_TYPE_PROP_CNLS = 89,  // Proprietary Connectionless Proto
            IF_TYPE_HOSTPAD = 90,  // CCITT-ITU X.29 PAD Protocol
            IF_TYPE_TERMPAD = 91,  // CCITT-ITU X.3 PAD Facility
            IF_TYPE_FRAMERELAY_MPI = 92,  // Multiproto Interconnect over FR
            IF_TYPE_X213 = 93,  // CCITT-ITU X213
            IF_TYPE_ADSL = 94,  // Asymmetric Digital Subscrbr Loop
            IF_TYPE_RADSL = 95,  // Rate-Adapt Digital Subscrbr Loop
            IF_TYPE_SDSL = 96,  // Symmetric Digital Subscriber Loop
            IF_TYPE_VDSL = 97,  // Very H-Speed Digital Subscrb Loop
            IF_TYPE_ISO88025_CRFPRINT = 98,  // ISO 802.5 CRFP
            IF_TYPE_MYRINET = 99,  // Myricom Myrinet
            IF_TYPE_VOICE_EM = 100,  // Voice recEive and transMit
            IF_TYPE_VOICE_FXO = 101,  // Voice Foreign Exchange Office
            IF_TYPE_VOICE_FXS = 102,  // Voice Foreign Exchange Station
            IF_TYPE_VOICE_ENCAP = 103,  // Voice encapsulation
            IF_TYPE_VOICE_OVERIP = 104,  // Voice over IP encapsulation
            IF_TYPE_ATM_DXI = 105,  // ATM DXI
            IF_TYPE_ATM_FUNI = 106,  // ATM FUNI
            IF_TYPE_ATM_IMA = 107,  // ATM IMA
            IF_TYPE_PPPMULTILINKBUNDLE = 108,  // PPP Multilink Bundle
            IF_TYPE_IPOVER_CDLC = 109,  // IBM ipOverCdlc
            IF_TYPE_IPOVER_CLAW = 110,  // IBM Common Link Access to Workstn
            IF_TYPE_STACKTOSTACK = 111,  // IBM stackToStack
            IF_TYPE_VIRTUALIPADDRESS = 112,  // IBM VIPA
            IF_TYPE_MPC = 113,  // IBM multi-proto channel support
            IF_TYPE_IPOVER_ATM = 114,  // IBM ipOverAtm
            IF_TYPE_ISO88025_FIBER = 115,  // ISO 802.5j Fiber Token Ring
            IF_TYPE_TDLC = 116,  // IBM twinaxial data link control
            IF_TYPE_GIGABITETHERNET = 117,
            IF_TYPE_HDLC = 118,
            IF_TYPE_LAP_F = 119,
            IF_TYPE_V37 = 120,
            IF_TYPE_X25_MLP = 121,  // Multi-Link Protocol
            IF_TYPE_X25_HUNTGROUP = 122,  // X.25 Hunt Group
            IF_TYPE_TRANSPHDLC = 123,
            IF_TYPE_INTERLEAVE = 124,  // Interleave channel
            IF_TYPE_FAST = 125,  // Fast channel
            IF_TYPE_IP = 126,  // IP (for APPN HPR in IP networks)
            IF_TYPE_DOCSCABLE_MACLAYER = 127,  // CATV Mac Layer
            IF_TYPE_DOCSCABLE_DOWNSTREAM = 128,  // CATV Downstream interface
            IF_TYPE_DOCSCABLE_UPSTREAM = 129,  // CATV Upstream interface
            IF_TYPE_A12MPPSWITCH = 130,  // Avalon Parallel Processor
            IF_TYPE_TUNNEL = 131,  // Encapsulation interface
            IF_TYPE_COFFEE = 132,  // Coffee pot
            IF_TYPE_CES = 133,  // Circuit Emulation Service
            IF_TYPE_ATM_SUBINTERFACE = 134,  // ATM Sub Interface
            IF_TYPE_L2_VLAN = 135,  // Layer 2 Virtual LAN using 802.1Q
            IF_TYPE_L3_IPVLAN = 136,  // Layer 3 Virtual LAN using IP
            IF_TYPE_L3_IPXVLAN = 137,  // Layer 3 Virtual LAN using IPX
            IF_TYPE_DIGITALPOWERLINE = 138,  // IP over Power Lines
            IF_TYPE_MEDIAMAILOVERIP = 139,  // Multimedia Mail over IP
            IF_TYPE_DTM = 140,  // Dynamic syncronous Transfer Mode
            IF_TYPE_DCN = 141,  // Data Communications Network
            IF_TYPE_IPFORWARD = 142,  // IP Forwarding Interface
            IF_TYPE_MSDSL = 143,  // Multi-rate Symmetric DSL
            IF_TYPE_IEEE1394 = 144,  // IEEE1394 High Perf Serial Bus
            IF_TYPE_RECEIVE_ONLY = 145 // TV adapter type
        }
        public enum IP_SUFFIX_ORIGIN : uint
        {
            /// IpSuffixOriginOther -> 0
            IpSuffixOriginOther = 0,
            IpSuffixOriginManual,
            IpSuffixOriginWellKnown,
            IpSuffixOriginDhcp,
            IpSuffixOriginLinkLayerAddress,
            IpSuffixOriginRandom,
        }
        public enum IP_PREFIX_ORIGIN : uint
        {
            /// IpPrefixOriginOther -> 0
            IpPrefixOriginOther = 0,
            IpPrefixOriginManual,
            IpPrefixOriginWellKnown,
            IpPrefixOriginDhcp,
            IpPrefixOriginRouterAdvertisement,
        }
        public enum IP_DAD_STATE : uint
        {
            /// IpDadStateInvalid -> 0
            IpDadStateInvalid = 0,
            IpDadStateTentative,
            IpDadStateDuplicate,
            IpDadStateDeprecated,
            IpDadStatePreferred,
        }
        public const int MAX_ADAPTER_ADDRESS_LENGTH = 8;
        public const int MAX_ADAPTER_NAME_LENGTH = 256;
    
        [StructLayout(LayoutKind.Sequential)]
        public struct SOCKADDR
        {
            /// u_short->unsigned short
            public ushort sa_family;
    
            /// char[14]
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 14)]
            public byte[] sa_data;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct SOCKET_ADDRESS
        {
            public IntPtr lpSockAddr;
            public int iSockaddrLength;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct IP_ADAPTER_UNICAST_ADDRESS
        {
            public UInt64 Alignment;
            public IntPtr Next;
            public SOCKET_ADDRESS Address;
            public IP_PREFIX_ORIGIN PrefixOrigin;
            public IP_SUFFIX_ORIGIN SuffixOrigin;
            public IP_DAD_STATE DadState;
            public uint ValidLifetime;
            public uint PreferredLifetime;
            public uint LeaseLifetime;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct IP_ADAPTER_ADDRESSES
        {
            public UInt64 Alignment;
            public IntPtr Next;
            public IntPtr AdapterName;
            public IntPtr FirstUnicastAddress;
            public IntPtr FirstAnycastAddress;
            public IntPtr FirstMulticastAddress;
            public IntPtr FirstDnsServerAddress;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string DnsSuffix;
            [System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)]
            public string Description;
            [System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPWStr)]
            public string FriendlyName;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst=MAX_ADAPTER_ADDRESS_LENGTH)]
            public byte[] PhysicalAddress;
            public uint PhysicalAddressLength;
            public uint Flags;
            public uint Mtu;
            public IF_TYPE IfType;
            public IF_OPER_STATUS OperStatus;
            uint Ipv6IfIndex;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public uint[] ZoneIndices;
            public IntPtr FirstPrefix;
        }

        [DllImport("iphlpapi.dll")]
        public static extern ERROR GetAdaptersAddresses(uint Family, uint Flags, IntPtr Reserved, IntPtr pAdapterAddresses, ref uint pOutBufLen);


        #region constants

        public const int MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
        public const int ERROR_BUFFER_OVERFLOW = 111;
        public const int MIB_IF_TYPE_OTHER = 1;
        public const int MIB_IF_TYPE_ETHERNET = 6;
        public const int MIB_IF_TYPE_TOKENRING = 9;
        public const int MIB_IF_TYPE_FDDI = 15;
        public const int MIB_IF_TYPE_PPP = 23;
        public const int MIB_IF_TYPE_LOOPBACK = 24;
        public const int MIB_IF_TYPE_SLIP = 28;
        public const int MIB_IF_TYPE_IEEE80211 = 71;
        
        #endregion

        #region structures

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct IP_ADAPTER_INFO
        {
            public IntPtr Next;
            public Int32 ComboIndex;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_NAME_LENGTH + 4)]
            public string AdapterName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_ADAPTER_DESCRIPTION_LENGTH + 4)]
            public string AdapterDescription;
            public UInt32 AddressLength;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_ADAPTER_ADDRESS_LENGTH)]
            public byte[] Address;
            public Int32 Index;
            public UInt32 Type;
            public UInt32 DhcpEnabled;
            public IntPtr CurrentIpAddress;
            public IP_ADDR_STRING IpAddressList;
            public IP_ADDR_STRING GatewayList;
            public IP_ADDR_STRING DhcpServer;
            public bool HaveWins;
            public IP_ADDR_STRING PrimaryWinsServer;
            public IP_ADDR_STRING SecondaryWinsServer;
            public Int32 LeaseObtained;
            public Int32 LeaseExpires;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct IP_ADDR_STRING
        {
            public IntPtr Next;
            public IP_ADDRESS_STRING IpAddress;
            public IP_ADDRESS_STRING IpMask;
            public Int32 Context;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct IP_ADDRESS_STRING
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string Address;
        }



        #endregion

        #region PInvoke

        /// <summary>
        /// The GetAdaptersInfo function retrieves adapter information for the local computer
        /// </summary>
        /// <param name="pAdapterInfo">A pointer to a buffer that receives a linked list of IP_ADAPTER_INFO structures.</param>
        /// <param name="pBufOutLen">A pointer to a ULONG variable that specifies the size of the buffer pointed to by the pAdapterInfo parameter. If this size is insufficient to hold the adapter information, GetAdaptersInfo fills in this variable with the required size, and returns an error code of ERROR_BUFFER_OVERFLOW.</param>
        /// <returns>If the function succeeds, the return value is ERROR_SUCCESS (defined to the same value as NO_ERROR).</returns>
        [DllImport("iphlpapi.dll", CharSet = CharSet.Ansi)]
        public static extern int GetAdaptersInfo(IntPtr pAdapterInfo, ref Int64 pBufOutLen);

        #endregion        
    }
}